import random
from PIL import Image, ImageDraw, ImageFont


class pil():

    def __init__(self, width, height, mode=None, color=None):

        """
        初始化--> 画文本--> (画干扰效果)--> 显示
        :param mode: mode-->默认RGBA
        :param width: 验证码的宽
        :param height: 验证码的高
        :param color: (num, num, num)
        """
        self.mode = mode
        if mode:    # 默认RGBA
            self.mode = mode

        else:
            self.mode = 'RGBA'
        self.width = width
        self.text_total = ''
        self.height = height
        self.color = None
        if color:   # 默认(255, 255, 255)
            self._color = color

        else:
            self._color = (255, 255, 255)

        # 定义使用Image类实例化一个图片
        self.img = Image.new(mode=self.mode, size=(self.width, self.height), color=self._color)

    def draw_out(self, name):
        # 把生成的图片保存为"pic.png"格式
        with open('./' + name+'.png', 'wb') as f:
            self.img.save(f, format='png')

        # 显示图片
        # self.img.show()
        # # 创建BytesIO对象用于保存图像数据
        # image_memory = BytesIO()
        #
        # # 将图像保存到BytesIO对象，可以选择不同的格式，如JPEG, PNG等
        # self.img.save(image_memory, format='PNG')  # 这里以JPEG格式为例
        #
        # # 获取BytesIO中的图像数据（字节）
        # image_data = image_memory.getvalue()
        # # 使用BytesIO对象创建Image对象
        # image_data = BytesIO(image_data)
        # image = Image.open(image_data)
        #
        # # 显示图片
        # image_memory.close()
        # image.show()

    # 画文本
    def draw_text(self, font_path, num, number=True, a_font=False, A_font=False):
        """
        若要添加字样，则设为true，数字默认开启
        :param font_path: 字样文件
        :param num: 验证码字符个数
        :param number: 是否开启数字
        :param a_font: 是否开启小写字母
        :param A_font: 是否开启大写字母
        :return: None
        """
        self.img = Image.new(mode=self.mode, size=(self.width, self.height), color=self._color)
        draw = ImageDraw.Draw(self.img, mode=self.mode)

        # 定义字体
        font1 = font_path
        font = ImageFont.truetype(font1, 60)    # 字体大小

        data = self.get_font(number=number, a_font=a_font, A_font=A_font)
        for i in range(num):
            # 数字，大写字母，小谢字母
            text = random.choice(data)
            color = self.get_color()

            draw.text([i * 50 + 12, -10], text, color, font=font)

    def draw_text_rotate(self, font_path, num, number=True, a_font=False, A_font=False):
        """
        若要添加字样，则设为true，数字默认开启
        :param font_path: 字样文件
        :param num: 验证码字符个数
        :param number: 是否开启数字
        :param a_font: 是否开启小写字母
        :param A_font: 是否开启大写字母
        :return: None
        """

        self.img = Image.new(mode=self.mode, size=(self.width, self.height), color=self._color)

        font1 = font_path
        font = ImageFont.truetype(font1, 50)

        data = self.get_font(number=number, a_font=a_font, A_font=A_font)
        for i in range(num):
            # 数字，大写字母，小谢字母

            text = random.choice(data)
            self.text_total = self.text_total + text
            color = self.get_color()

            global IMG
            img0 = Image.new(mode=self.mode, size=(self.width, self.height),
                             color=(248, 248, 248))
            draw0 = ImageDraw.Draw(img0, mode='RGBA')
            draw0.text((0, 0), text, color, font=font)
            # 获得一个旋转字
            img1 = img0.rotate(random.uniform(-15, 15), Image.BILINEAR,
                               translate=((i * 45) + 30, 0), center=(0, 10),
                               expand=0)
            if i == 0:  # 当前旋转字与上一个叠加
                IMG = img1
            else:
                IMG = Image.composite(img1, IMG, img1)

        # print(self.text_total.lower())
        blank = Image.new(mode='RGBA', size=IMG.size, color=(248,) * 3)    # 白背景
        self.img = Image.composite(IMG, blank, IMG)     # 补全旋转字的空缺

    # 画干扰点
    def draw_point(self, num):
        # 生成img该对象上的画笔
        draw = ImageDraw.Draw(self.img, mode=self.mode)

        for i in range(num):
            x = random.randint(0, self.width)
            y = random.randint(0, self.height)
            color = self.get_color()

            draw.point([x, y], fill=color)
        # self.draw_out()

    # 画干扰园
    def draw_arc(self, num):
        # 生成img该对象上的画笔
        draw = ImageDraw.Draw(self.img, mode=self.mode)

        for i in range(num):
            x = random.randint(0, self.width)
            y = random.randint(0, self.height)
            color = self.get_color()

            draw.arc([x, y, x + 15, y + 15], 0, 360, fill=color)
        # self.draw_out()

    # 画干扰线
    def draw_line(self, num):
        # 生成img该对象上的画笔
        draw = ImageDraw.Draw(self.img, mode=self.mode)

        for i in range(num):
            x1 = random.randint(0, self.width)
            y1 = random.randint(0, self.height)
            x2 = random.randint(0, self.width)
            y2 = random.randint(0, self.height)
            color = self.get_color()

            draw.line([x1, y1, x2, y2], fill=color)
            # self.draw_out()

    def get_font(self, number=False, a_font=False, A_font=False):
        data = []
        if number:
            for i in range(0, 10):
                data.append(str(i))

        if A_font:
            for i in range(65, 91):
                data.append(chr(i))

        if a_font:
            for i in range(97, 123):
                data.append(chr(i))

        return data

    def get_color(self):
        self.color = (random.randint(0, self._color[0]),
                      random.randint(0, self._color[1]), random.randint(0, self._color[2]))
        return self.color


pil = pil(width=240, height=60)
pil.draw_text_rotate(font_path='fz.ttf', num=4, a_font=True, A_font=True)
pil.draw_point(1000)
pil.draw_line(15)

pil.draw_out(pil.text_total.lower())
pil.text_total = ''



